package com.tyqx.hashchainbackend.controller;

import com.tyqx.hashchainbackend.service.HashIndexService;
import com.tyqx.hashchainutil.common.*;

import org.json.JSONObject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;

import javax.annotation.Resource;
import java.io.*;
import java.util.*;

@RestController
@RequestMapping("/test")
public class Test {

    @Resource
    private HashIndexService hashIndexService;


    @RequestMapping("/method")
    public String i() throws Exception {
       /* CreateWallet createWallet = new CreateWallet();
        Long caIndex = 1L;
        String orgType = "peer";
        String caType = "msp";
        String secret = "123456";
        String userName = "User1";
        Long orgIndex = 0L;

        JSONObject insertObj = new JSONObject();
        insertObj.put("name", "zhang1");
        insertObj.put("sex", "11");
        insertObj.put("age", 50);
        insertObj.put("phone", 11);
        insertObj.put("attachment", "0");

        Path keyPath = (Path) Util.readUserContext(caType, userName, orgIndex).get("clientKeyPath");
        ChainCode chainCode=new ChainCode();
        Map<String,String> map=chainCode.insertHash(userName, insertObj, keyPath,"insertHash");
        HashIndex hashIndex=new HashIndex();
        hashIndex.setHashValue(map.get("hashValue"));
        hashIndex.setTxId(map.get("txid"));
        hashIndex.setBlockNum(Long.valueOf(map.get("blockNum")));
        boolean flag=hashIndexService.insertHashIndex(hashIndex);
        System.out.println(flag);*/

        /*String insertString = insertObj.toString();
        CryptoPrimitives suite = new CryptoPrimitives();
        suite.init();
        byte[] hashBytes = suite.hash(insertString.getBytes());
        String hashValue = Base64.getEncoder().encodeToString(hashBytes);

        List<HashIndex> hashIndexList = hashIndexService.getHashIndexByHashValue(hashValue);
        HashIndex hashIndex = hashIndexList.get(0);

        BlockData blockData = new BlockData();
        Map<String, String> map = blockData.getBlockByNum(hashIndex.getBlockNum());
        String blockDataStr = map.get("blockDataStr");

        JsonObject blockDataJson = new JsonParser().parse(blockDataStr).getAsJsonObject();
        JsonObject hashItemJson = blockData.getHashItemByTxId(blockDataJson, hashIndex.getTxId());
        String blockHashValue = hashItemJson.get("hashValue").toString();

        blockHashValue = blockHashValue.substring(blockHashValue.indexOf("\"") + 1, blockHashValue.lastIndexOf("\""));
        String blockHashSignature = hashItemJson.get("hashSignature").toString();
        blockHashSignature = blockHashSignature.substring(blockHashSignature.indexOf("\"") + 1, blockHashSignature.lastIndexOf("\""));
        if (blockHashValue.equals(hashValue)) {
            System.out.println("hash match");
        }

        Map<String, Object> pathMap = Util.readUserContext(caType, userName, orgIndex);
        Path caPath = (Path) pathMap.get("caPath");
        Path clientCertPath = (Path) pathMap.get("clientCertPath");
        Path clientKeyPath = (Path) pathMap.get("clientKeyPath");

        CryptoUtil cryptoUtil = new CryptoUtil();

        boolean flag = cryptoUtil.verify(clientCertPath, blockHashSignature, blockHashValue);
        System.out.println(flag);*/
        return "success";
    }

    public static void main(String[] args) throws Exception {

        CreateWallet createWallet = new CreateWallet();
        Long caIndex = 1L;
        String orgType = "peer";
        String caType = "tls";
        String secret = "123456";
        String userName = "User1";
        Long orgIndex = 0L;
        String COMPOSE_PROJECT_NAME="hashchain";

        /*createWallet.initCA(COMPOSE_PROJECT_NAME,1L, orgType, caType, secret, orgIndex);

        createWallet.registerUser(COMPOSE_PROJECT_NAME,caIndex, orgType, caType, secret, userName, orgIndex);
        createWallet.enrollUser(COMPOSE_PROJECT_NAME,caIndex, orgType, caType, secret, userName, orgIndex);
        createWallet.generateUserCA(COMPOSE_PROJECT_NAME,caIndex, orgType, caType, secret, userName, orgIndex);*/

        /*String docType = "HashItem";
        String itemId = "111";
        String hashValue = "222";
        String hashSignature = "444";
        ChainCode chainCode = new ChainCode();
        chainCode.insertHash(docType, itemId, hashValue, hashSignature);*/

        /*createWallet.enrollAdminUser();
        createWallet.enrollAdminUserTLS();

        String enrollmentSecret = createWallet.registerUser(userName, Config.ORG_AFFI_1);
        createWallet.enrollUser(userName, Config.ORG_AFFI_1, enrollmentSecret);

        String enrollmentSecretTLS = createWallet.registerUserTLS(userName, Config.ORG_AFFI_1);
        createWallet.enrollUserTLS(userName, Config.ORG_AFFI_1, enrollmentSecretTLS);*/

        JSONObject insertObj = new JSONObject();
        insertObj.put("name", "l");
        insertObj.put("sex", "0");
        insertObj.put("age", 100);
        insertObj.put("phone", 111);
        insertObj.put("attachment", "0");

        String insertString = insertObj.toString();
        /*CryptoPrimitives suite = new CryptoPrimitives();
        suite.init();
        byte[] hashBytes=suite.hash(insertString.getBytes());
        String hashValue = Base64.getEncoder().encodeToString(hashBytes);*/


       /*Path keyPath = Util.readUserContext(caType, userName, orgIndex);
        ChainCode chainCode=new ChainCode();
        Map<String,String> map=chainCode.insertHash(insertObj, keyPath);
        System.out.println("123");*/

        /*BlockData blockData=new BlockData();
        Map<String,String> map=blockData.getBlockByNum(18L);
        String blockDataStr=map.get("blockDataStr");
        JsonObject blockDataJson=new JsonParser().parse(blockDataStr).getAsJsonObject();
        blockData.getHashItemByTxId(blockDataJson,"");
        System.out.println(blockDataJson);*/

        Map<String, Object> configtx = null;
        Map<String, Object> configtxOrgnizations = null;

        StringWriter yamlStr = new StringWriter();
        DumperOptions options = new DumperOptions();
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        options.setSplitLines(true);
        options.setPrettyFlow(true);

        try {


            String configtxUrl = "/Users/zhangzhemin/dynamicChain/cryptos/fabric-ca-client/config/configtx.yaml";
            String configtxOrgnizationsUrl = "/Users/zhangzhemin/dynamicChain/configtxTemplates/configtx-orgnizations.yaml";
            FileInputStream configtxFIS = new FileInputStream(configtxUrl);
            FileInputStream configtxOrgnizationsFIS = new FileInputStream(configtxOrgnizationsUrl);
            Yaml yaml = new Yaml(options);
            configtx = (Map<String, Object>) yaml.load(configtxFIS);
            configtxOrgnizations = (Map<String, Object>) yaml.load(configtxOrgnizationsFIS);

            ArrayList<Map<String, Object>> organizations = (ArrayList<Map<String, Object>>) configtx.get("Organizations");
            ArrayList<Map<String, Object>> organizationsTemp = (ArrayList<Map<String, Object>>) configtxOrgnizations.get("Organizations");
            Map<String, Object> peerOrg = organizationsTemp.get(1);
            peerOrg.replace("Name", "Org3");
            peerOrg.replace("ID", "Org3MSP");
            peerOrg.replace("MSPDir", "crypto-config/peerOrganizations/org3.hashchain.com/msp");
            ArrayList<Map<String, Object>> anchorPeers = (ArrayList<Map<String, Object>>) peerOrg.get("AnchorPeers");
            for (Map<String, Object> anchorPeer: anchorPeers){
                anchorPeer.replace("Host", "peer0.org3.hashchain.com");
            }
            Map<String, Object> policies = (Map<String, Object>) peerOrg.get("Policies");
            for (String key : policies.keySet()){
                Map<String, Object> policy = (Map<String, Object>) policies.get(key);
                if (key.equals("Readers")){
                    policy.replace("Rule", "OR('Org3MSP.admin', 'Org3MSP.peer', 'Org3MSP.client')");

                } else if (key.equals("Writers")){
                    policy.replace("Rule", "OR('Org3MSP.admin', 'Org3MSP.client')");

                } else if (key.equals("Admins")){
                    policy.replace("Rule", "OR('Org3MSP.admin')");

                } else if (key.equals("Endorsement")){
                    policy.replace("Rule", "OR('Org3MSP.member')");
                }
            }

            organizationsTemp.remove(2);
            organizationsTemp.remove(0);



            organizations.add(peerOrg);

            Map<String, Object> profiles = (Map<String, Object>) configtx.get("Profiles");

            Map<String, Object> hashchainOrdererGenesis = (Map<String, Object>) profiles.get("HashchainOrdererGenesis");
            Map<String, Object> consortiumsOrdererGenesis = (Map<String, Object>) hashchainOrdererGenesis.get("Consortiums");
            Map<String, Object> sampleConsortiumOrdererGenesis = (Map<String, Object>) consortiumsOrdererGenesis.get("SampleConsortium");
            List<Map<String, Object>> organizationsOrdererGenesis = (List<Map<String, Object>>) sampleConsortiumOrdererGenesis.get("Organizations");
            organizationsOrdererGenesis.add(peerOrg);

            Map<String, Object> hashchainChannel = (Map<String, Object>) profiles.get("HashchainChannel");
            Map<String, Object> applicationChannel = (Map<String, Object>) hashchainChannel.get("Application");
            List<Map<String, Object>> organizationsChannel = (List<Map<String, Object>>) applicationChannel.get("Organizations");
            organizationsChannel.add(peerOrg);


            File configtxYaml = new File("/Users/zhangzhemin/dynamicChain/cryptos/org3-artifects/configtx.yaml");
            FileWriter configtxFileWriter = new FileWriter(configtxYaml);


//            yaml.dump(configtx, configtxFileWriter);
            yaml.dump(configtxOrgnizations, configtxFileWriter);

            System.out.println(configtx.toString());

        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
        System.out.println(configtx.toString());


    }
}
